/* 
 * File:   utils.h
 * Author: alrojas
 *
 * Created on 31 de marzo de 2014, 11:47
 */

#ifndef UTILS_H
#define	UTILS_H

#include <cstdlib>
#include "cv.h"
#include "highgui.h"
#include <math.h>

using namespace std;
using namespace cv;

RNG rng(time(NULL));

class utils {
public:
    
    static string Point2String(Point punto){
    
        stringstream ss;
        ss << "(";
        ss << punto.x;
        ss << ",";
        ss << punto.y;
        ss << ")";

        return ss.str();

    }
    
    static string Point2String(Point punto, int indice){
    
        stringstream ss;
        ss << indice;
        ss << " (";
        ss << punto.x;
        ss << ",";
        ss << punto.y;
        ss << ")";

        return ss.str();

    }
   
    static string Point2String(string id ,int indice){
    
        stringstream ss;
        ss << id;
        //ss << "-";
        ss << indice;
        return ss.str();

    }
    
    static double AngleOfPoint(Point pivot, Point point){
        
        double x = point.x - pivot.x;
        double y = point.y - pivot.y;
        
        double angle = atan2 (y,x); // Radians
        
        if(angle < 0){
            angle += (2 * M_PI);
        }
  
        return angle * 180.0f / M_PI; 

    }
    
    static int IndexOf(vector < Point > vinput, Point pinput){
        for(uint i = 0; i < vinput.size(); i++){
            if(vinput[i] == pinput) return i;
        }
        return -1;
    }
    
    static double EuclideanDistance(Point & first, Point & second){
    
        return sqrt(pow(second.x - first.x,2) + pow(second.y - first.y,2));

    }
    
    static bool IsPointInsidePolygon(vector < Point > & contour, Point point){
        int polySides = (int)contour.size();  

        int i, j = polySides - 1;
        bool oddNodes = false;

        for (i = 0; i < polySides; i++){
            if (((contour[i].y < point.y && contour[j].y >= point.y)
                || (contour[j].y < point.y && contour[i].y >= point.y))
                && (contour[i].x <= point.x || contour[j].x <= point.x)){
                oddNodes ^= (contour[i].x + ( point.y - contour[i].y ) / ( contour[j].y - contour[i].y ) * ( contour[j].x - contour[i].x ) < point.x); 
            }
            j = i; 
        }

        return oddNodes; 
    }
    
    static struct myclass1 {

        bool operator() (Point pt1,Point pt2) { return (pt1.y < pt2.y);}

    } myobject1;

    static struct myclass2 {

        bool operator() (Point pt1,Point pt2) { return (pt1.y > pt2.y);}

    } myobject2;
    
    static struct myclass3 {

        bool operator() (Point pt1,Point pt2) { return (pt1.x < pt2.x);}

    } myobject3;
    
    static struct myclass4 {

        bool operator() (Point pt1,Point pt2) { return (pt1.x > pt2.x);}

    } myobject4;
    
    static bool AreAllPointsInside(vector < Point > vinput1, vector < Point > vinput2){
        
        vector < Point > lvinput1 = vinput1;
        vector < Point > output;
        
        std::sort(lvinput1.begin(),lvinput1.end(),myobject3);
        Point mxl1 = lvinput1[0]; 

        std::sort(lvinput1.begin(),lvinput1.end(),myobject4);
        Point mxr1 = lvinput1[0];

        std::sort(lvinput1.begin(),lvinput1.end(),myobject1);        
        Point myb1 = lvinput1[0];                
        
        std::sort(lvinput1.begin(),lvinput1.end(),myobject2);        
        Point myt1 = lvinput1[0];
                
        vector < Point > lvinput2 = vinput2;

        std::sort(lvinput2.begin(),lvinput2.end(),myobject3);
        Point mxl2 = lvinput2[0]; 

        std::sort(lvinput2.begin(),lvinput2.end(),myobject4);
        Point mxr2 = lvinput2[0];

        std::sort(lvinput2.begin(),lvinput2.end(),myobject1);        
        Point myb2 = lvinput2[0];                
        
        std::sort(lvinput2.begin(),lvinput2.end(),myobject2);        
        Point myt2 = lvinput2[0];
        
        if(mxl1.x < mxl2.x) return false;
        if(mxr1.x > mxr2.x) return false;
        if(myb1.x < myb2.x) return false;
        if(myt1.x > myt2.x) return false;
                
        return true;
        
    }
    
};

#endif	/* UTILS_H */

